package cn.pilipa.common.config.swagger;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import springfox.documentation.spring.web.PropertySourcedMapping;
import java.lang.reflect.Method;
import java.util.Optional;


public class Swagger2ControllerRequestMappingHandlerMapping
    extends ProxiedControllerRequestMappingHandlerMapping {
  private final Environment environment;

  /**
   * 构造器.
   * @param environment 参数
   * @param handler 参数
   * @param basePath 参数
   */
  public Swagger2ControllerRequestMappingHandlerMapping(
      Environment environment,
      Object handler,
      String basePath) {

    super(handler, basePath);
    this.environment = environment;
  }

  @Override
  protected void doMapping(
      Class<?> clazz,
      Method method,
      RequestMappingInfo mapping,
      HandlerMethod handlerMethod) {

    PropertySourcedMapping mapper = AnnotationUtils
        .getAnnotation(method, PropertySourcedMapping.class);

    if (mapper != null) {
      String mappingPath = mappingPath(mapper);
      if (mappingPath != null) {
        mappingPath = basePath + mappingPath;

        logger.info(String.format(
            "Mapped URL path [%s] onto method [%s]",
            mappingPath,
            handlerMethod.toString()));
        handlerMethods.put(mappingPath, handlerMethod);
      } else {
        super.doMapping(clazz, method, mapping, handlerMethod);
      }
    }
  }

  private String mappingPath(final PropertySourcedMapping mapper) {

    final String key = mapper.propertyKey();
    return Optional.ofNullable(environment.getProperty(key))
        .map(input -> input.replace(String.format("${%s}", key), input))
        .orElse(null);
  }
}